package com.coffee.redis;

import com.alibaba.fastjson2.support.spring.data.redis.GenericFastJsonRedisSerializer;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;

/**
 * @author SongKui
 * @since 2020/5/18 0018
 **/
@Configuration
@Slf4j
public class RedisSourceConfiguration {



    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory){

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        GenericFastJsonRedisSerializer valueSerializer = new GenericFastJsonRedisSerializer();
        //GenericJackson2JsonRedisSerializer hsSerializer = new GenericJackson2JsonRedisSerializer();
        StringRedisSerializer keySerializer = new StringRedisSerializer();

        template.setConnectionFactory(redisConnectionFactory);
        template.setDefaultSerializer(valueSerializer);

        template.setKeySerializer(keySerializer);
        template.setValueSerializer(valueSerializer);

        template.setHashKeySerializer(valueSerializer);
        template.setHashValueSerializer(valueSerializer);

        return template;
    }


    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
        return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory).build();
    }


    @Bean
    public RedisMessageListenerContainer container(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(lettuceConnectionFactory);
        return container;
    }

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient(RedisProperties redisProperties) {
        Config config = new Config();
        String password = redisProperties.getPassword();
        config.useSingleServer()
                .setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort())
                .setPassword(StringUtils.hasLength(password) ? password : null)
                .setDatabase(redisProperties.getDatabase());
        config.setThreads(Runtime.getRuntime().availableProcessors() * 2);
        config.setEventLoopGroup(new NioEventLoopGroup());
        return Redisson.create(config);
    }


    @Bean
    public CoffeeRedisLockWrapper coffeeRedisLockWrapper() {
        return new CoffeeRedisLockWrapper();
    }



}
